package cn.yshujia.service.impl;

import cn.yshujia.domain.dto.PageDTO;
import cn.yshujia.domain.entity.Album;
import cn.yshujia.domain.vo.AlbumVO;
import cn.yshujia.domain.vo.PageVO;
import cn.yshujia.enums.MinioFolder;
import cn.yshujia.mapper.AlbumMapper;
import cn.yshujia.repository.AlbumRepository;
import cn.yshujia.utils.IDUtils;
import cn.yshujia.utils.MinioUtils;
import cn.yshujia.utils.PageUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author YShuJia
 * @create 2025/3/4
 * @description AlbumServiceImpl
 */

@Service
public class AlbumServiceImpl extends ServiceImpl<AlbumMapper, Album> implements IService<Album> {
	
	@Resource
	public AlbumMapper mapper;
	
	@Resource
	public AlbumRepository repository;
	
	public AlbumVO selectById(Long id) {
		return repository.selectById(id);
	}
	
	public PageVO<AlbumVO> page(PageDTO dto) {
		return repository.pageByLabelId(dto);
	}
	
	public PageVO<AlbumVO> adminPage(PageDTO dto) {
		QueryWrapper<Album> wrapper = PageUtils.createAlbumWrapper(dto);
		IPage<Album> page = mapper.selectPage(new Page<>(dto.getCurrent(), dto.getSize()), wrapper);
		// 创建VO集合
		if (!ObjectUtils.isEmpty(page) && !ObjectUtils.isEmpty(page.getRecords())) {
			return PageUtils.getPage(dto, repository.createVOList(page.getRecords()), page.getTotal());
		}
		return new PageVO<>();
	}
	
	
	@Transactional (rollbackFor = Exception.class)
	public Boolean insert(MultipartFile[] files, Album album) {
		List<String> urls = MinioUtils.upload(files, MinioFolder.ALBUM);
		album.setPath(String.join(",", urls));
		album.setId(IDUtils.getId());
		int n = mapper.insert(album);
		if (n > 0) {
			repository.del();
			return true;
		}
		MinioUtils.delete(urls);
		return false;
	}
	
	@Transactional (rollbackFor = Exception.class)
	public Boolean update(MultipartFile[] files, Album album) {
		Album old = mapper.selectById(album.getId());
		if (ObjectUtils.isEmpty(old)) {
			return false;
		}
		int n;
		// 如果没有删除图片，并且没上传新图片，则直接更新数据
		if (old.getPath().equals(album.getPath()) && ObjectUtils.isEmpty(files)) {
			n = mapper.updateById(album);
			repository.del();
		} else {
			// 上传新图片
			List<String> urls = MinioUtils.upload(files, MinioFolder.ALBUM);
			String newPath = String.join(",", urls);
			
			Set<String> oldUrls = new HashSet<>(Set.of(old.getPath().split(",")));
			
			Set<String> newUrls = new HashSet<>(Set.of(album.getPath().split(",")));
			// 在 oldUrls 中 移除 newUrls 包含的元素
			newUrls.forEach(oldUrls::remove);
			
			// 如果 newList 不为空 (为空则表示以前的图片全部删除重新上传)，则将 newPath 拼接到 album.path 中
			if (!ObjectUtils.isEmpty(newUrls)) {
				album.setPath(album.getPath() + "," + newPath);
			} else {
				album.setPath(newPath);
			}
			// 更新数据
			n = mapper.updateById(album);
			if (n > 0) {
				// 删除 oldList 中有但 newList 中没有的图片
				MinioUtils.delete(oldUrls);
				repository.del();
			} else {
				// 更新失败，删除新上传的图片
				MinioUtils.delete(urls);
			}
		}
		return n > 0;
	}
	
	@Transactional (rollbackFor = Exception.class)
	public Boolean remove(List<Long> ids) {
		int n = mapper.deleteByIds(ids);
		if (n > 0) {
			repository.del();
		}
		return n > 0;
	}
	
}
